#include <iostream>
#include <fstream>
#include <stdlib.h>

#define FUNCIONES_HASH 16
#define AUMENTO 2

struct candidato_t {

    int documentoA;
    int documentoB;
    int frecuencia;
    
};

using namespace std;


void agregarCandidatosEnBloque(int ** bloque, int tamanioBloque, candidato_t * candidatos, int numeroDeDocs, int* numeroDeCandidatos, int* tamanioMaximo);


void listarCandidato(candidato_t candidatoQueAgrego, candidato_t* candidatos, int* numeroDeCandidatos, int* tamanioMaximo);


/* debe recibir el vector de candidatos con espacio igual a la cantidad de documentos */

int buscarCandidatos(int ** matrizHashMin, int tamanioBloque, candidato_t * unosCandidatos, int numeroDeDocs, int* tamanioMaximo){
  
	int ** bloque = (int**) malloc (sizeof(int*)*tamanioBloque); //pido memoria para un bloque de la matrizHashMin
	int numeroDeBloques = FUNCIONES_HASH / tamanioBloque;
	int acumulador = 0;
	int numeroDeCandidatos = 0;

	for(int i=0; i<numeroDeBloques; i++){

	for(int j=0; j< tamanioBloque; j++){

	  bloque[j] = matrizHashMin[j+acumulador*tamanioBloque];

	}
	cout << "bloque ok"<< endl<< endl;

	acumulador++;

	agregarCandidatosEnBloque(bloque, tamanioBloque, unosCandidatos, numeroDeDocs, &numeroDeCandidatos, tamanioMaximo);

	}

	free(bloque);

	return numeroDeCandidatos;
}




void agregarCandidatosEnBloque(int ** bloque, int tamanioBloque, candidato_t * candidatos, int numeroDeDocs, int* numeroDeCandidatos, int* tamanioMaximo){
  
  int parteDelBloque = 0;
  
  for(int i=0; i<numeroDeDocs;i++){

    int documentoComparado = i + 1;
     
     while (documentoComparado < numeroDeDocs){
     
		while ((documentoComparado < numeroDeDocs) && (bloque[parteDelBloque][i] != bloque[parteDelBloque][documentoComparado])){
		
			documentoComparado++;
			
		}
  
		while ((documentoComparado < numeroDeDocs) && (parteDelBloque < tamanioBloque) && (bloque[parteDelBloque][i] == bloque[parteDelBloque][documentoComparado])){
		
			parteDelBloque++;
	
			if((documentoComparado < numeroDeDocs) && (parteDelBloque < tamanioBloque) && (bloque[parteDelBloque][i] != bloque[parteDelBloque][documentoComparado])){
  
				documentoComparado++;
				parteDelBloque = 0;
		
			}
		}
		if(parteDelBloque == tamanioBloque){
      
			candidato_t candidatoAuxiliar;
			  
			candidatoAuxiliar.documentoA = i;
			candidatoAuxiliar.documentoB = documentoComparado;
			candidatoAuxiliar.frecuencia = 1;
			  
			listarCandidato(candidatoAuxiliar, candidatos, numeroDeCandidatos, tamanioMaximo);
			parteDelBloque = 0;
			documentoComparado++;
			
			
		}
  
    }
    
  } 

}
  
  
void listarCandidato(candidato_t candidatoQueAgrego, candidato_t* candidatos, int* numeroDeCandidatos, int* tamanioMaximo){

  int contador = 0;
  
  while((contador < (*numeroDeCandidatos)) && ((candidatoQueAgrego.documentoA != candidatos[contador].documentoA) || (candidatoQueAgrego.documentoB != candidatos[contador].documentoB))) {
    
    //cout << candidatos[contador].documentoA << ";" << candidatos[contador].documentoB <<  endl;
    contador++;
  
  }
    
  if(contador == (*numeroDeCandidatos)){
	
	cout << "incremento" << endl << endl;
  
    (*numeroDeCandidatos)++; //incremento el numero de candidatos
    
    candidatos[(*numeroDeCandidatos)-1] = candidatoQueAgrego;
	
	if((*tamanioMaximo) == (*numeroDeCandidatos)){
	
		(*tamanioMaximo)+= (*tamanioMaximo); // si no me alcanza el tamaño lo aumento
		
		cout << "mas memoria pls" << endl << endl;
		
		candidatos= (candidato_t*)realloc(candidatos, sizeof(candidato_t)*(*tamanioMaximo));
		
	}

  }
  else {
    
    /* si el contador no llegó al último, quiere decir que hay una repetición de candidatos, entonces incremento su frecuencia */
    
    (candidatos[contador].frecuencia)++; 
    
  }
  
}


